package com.takanafu.haru.core{
	import com.takanafu.haru.code.CodeBase;
	import com.takanafu.haru.code.CodeObject;
	import com.takanafu.haru.code.CodeSymbol;
	import com.takanafu.haru.code.builtins.Confirm;
	import com.takanafu.haru.code.builtins.HaruAlert;
	import com.takanafu.haru.code.builtins.LoadXML;
	import com.takanafu.haru.code.builtins.Print;
	
	import flash.utils.Dictionary;
	
	import mx.controls.TextArea;
	
	public class GlobalManager{
		public static var _globals:Dictionary = new Dictionary();
		public static var _frames:Array = new Array();
		// 組み込み関数を増やす時はここに追加
		_globals[CodeSymbol.intern("print")] = new Print();
		_globals[CodeSymbol.intern("loadXML")] = new LoadXML();
		_globals[CodeSymbol.intern("confirm")] = new Confirm();
		_globals[CodeSymbol.intern("alert")] = new HaruAlert();
		
		private static var _stdOut:TextArea = null;
		
		public static function set stdOut(ta:TextArea):void{
			_stdOut = ta;
		}
		public static function get stdOut():TextArea{
			return _stdOut;
		}
		
		public function GlobalManager(){
			super();
		}
		
		public static function pushObject(obj:CodeObject):void{
			var frame:Frame = new Frame(obj);
			
			_frames.push(frame);
		}
		public static function popObject():void{
			_frames.pop();
		}
		public static function pushLocals(table:Dictionary):void{
			if(_frames.length > 0){
				var frame:Frame = _frames[0];
				
				frame.pushLocals(table);
			}
		}
		public static function popLocals():void{
			if(_frames.length > 0){
				var frame:Frame = _frames[0];
				
				frame.popLocals();
			}
		}
		
		public static function hasSymbol(sym:CodeSymbol):Boolean{
			for(var prop:Object in _globals){
				if(_globals[prop] == sym)return true;
			}
			return false; 
		}
		public static function getSymbolValue(sym:CodeSymbol):CodeBase{
			return _globals[sym];
		}
		public static function setSymbol(sym:CodeSymbol,code:CodeBase):void{
			_globals[sym] = code;
		}
		public static function def(sym:CodeSymbol,code:CodeBase):void{
			var frame:Frame = _frames[0];
			
			if(frame.size() != 0){
				frame.def(sym,code);
				return;
			}
			if(_globals.hasOwnProperty(sym) == true){
				throw new Error("変数" + sym.toString() + "は定義済みです。");
			}
			_globals[sym] = code;
		}
	}
}